
#include <string>
#include "cv.h"
#include "highgui.h"

using namespace std;

enum enum_states
{
	STATE_NOFACE,
	STATE_GOTFACE,
	STATE_MAYBEHAND,
	STATE_GOTHAND
};

class CDetector
{
public:
// FUNCTIONS

	CDetector();
	~CDetector();
	double sumPixels(cv::Mat *matrix, cv::Rect *roi);
	double sumWhitePixels(cv::Mat *matrix, cv::Rect *roi);
	void extractFaceColor(IplImage* src);
	void createWindows();
	void destroyWindows();
	bool grabNewFrame();
	void fixFrame();
	void copyFrame();
	void findFace( IplImage* img );
	void produceMask( IplImage* img );
	void showMask();
	void showCam();
	void drawFaceFrame( IplImage* img );
	void searchForHand( IplImage* img );
	void moveMouse();
	void checkForClick(cv::Rect *old);
	void searchForWave( IplImage* img );
	void updateHandRect( IplImage* img );
	int boundsCheck(int val, int max);
	void boundsCheck(cv::Rect *re, int maxx, int maxy);

// VARIABLES

	int mState;

	// Create memory for calculations
	CvMemStorage* storage;

	// Create a new Haar classifier
	CvHaarClassifierCascade* cascade;
	int avgH;
	int avgS;
	int avgV;
	string cascade_name;

    // Structure for getting video from camera or avi
    CvCapture* capture;

    // Images to capture the frame from video or camera or from file
    IplImage *frame;
	IplImage *frame_copy;
    IplImage *old_frame;
    IplImage *end_result;
	IplImage* hsv_image;
	IplImage* hsv_mask;
	IplImage* snail_result;
	IplImage* snail_temp;
	IplImage* snail_temp2;
	IplImage* snail_old;
	IplImage* snail_gray;

	// matrixes to produce the motion detection snail trail
	cv::Mat oldMat, newMat, snailTrailMat;

	// define constant
	static const int HSVMODE = 1;
	static const int JOYSTICK = 0;

	// rectangles for the face and hand
	CvRect faceRect;
	CvRect handRect;
	CvRect normalHandSize;
	CvPoint handSpeed;
	long frameCounter;
	static const int CLICKFRAMES = 3;
	double clickSpeeds[CLICKFRAMES];
	bool mouseIsDown;
	double old_mouseX;
	double old_mouseY;
	double new_mouseX;
	double new_mouseY;
};
